home *** CD-ROM | disk | FTP | other *** search
/ PC World 2003 January / PCWorld_2003-01_cd.bin / Software / Vyzkuste / rychlokurz / httrack.exe / {app} / src / htsalias.c < prev    next >
C/C++ Source or Header  |  2002-11-17  |  18KB  |  527 lines

  1. /* ------------------------------------------------------------ */
  2. /*
  3. HTTrack Website Copier, Offline Browser for Windows and Unix
  4. Copyright (C) Xavier Roche and other contributors
  5.  
  6. This program is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU General Public License
  8. as published by the Free Software Foundation; either version 2
  9. of the License, or any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  19.  
  20.  
  21. Important notes:
  22.  
  23. - We hereby ask people using this source NOT to use it in purpose of grabbing
  24. emails addresses, or collecting any other private information on persons.
  25. This would disgrace our work, and spoil the many hours we spent on it.
  26.  
  27.  
  28. Please visit our Website: http://www.httrack.com
  29. */
  30.  
  31.  
  32. /* ------------------------------------------------------------ */
  33. /* File: htsalias.c subroutines:                                */
  34. /*       alias for command-line options and config files        */
  35. /* Author: Xavier Roche                                         */
  36. /* ------------------------------------------------------------ */
  37.  
  38. #include <stdio.h>
  39. #include <stdlib.h>
  40. #include <string.h>
  41. #include "htsbase.h"
  42. #include "htsalias.h"
  43. #include "htsglobal.h"
  44. void linput(FILE* fp,char* s,int max);
  45. void hts_lowcase(char* s);
  46.  
  47. #define _NOT_NULL(a) ( (a!=NULL) ? (a) : "" )
  48. #define is_realspace(c) (strchr(" \x0d\x0a\x09\x0b\x0c",(c))!=NULL)
  49.  
  50. // COPY OF cmdl_ins in htsmain.c
  51. // Insert a command in the argc/argv
  52. #define cmdl_ins(token,argc,argv,buff,ptr) \
  53.   { \
  54.   int i; \
  55.   for(i=argc;i>0;i--)\
  56.   argv[i]=argv[i-1];\
  57.   } \
  58.   argv[0]=(buff+ptr); \
  59.   strcpybuff(argv[0],token); \
  60.   ptr += (strlen(argv[0])+1); \
  61.   argc++
  62. // END OF COPY OF cmdl_ins in htsmain.c
  63.  
  64.  
  65. /*
  66.   Aliases for command-line and config file definitions
  67.   These definitions can be used:
  68.   in command line:
  69.   --sockets=8       --cache=0
  70.   --sockets 8       --cache off
  71.                     --nocache
  72.   -c8               -C0
  73.   in config file:
  74.   sockets=8         cache=0
  75.   set sockets 8     cache off
  76.  
  77. */
  78. /*
  79.   single : no options
  80.   param  : this option allows a number parameter (1, for example) and can be mixed with other options (R1C1c8)
  81.   param1 : this option must be alone, and needs one distinct parameter (-P <path>)
  82.   param0 : this option must be alone, but the parameter should be put together (+*.gif)
  83. */
  84. const char hts_optalias[][4][64] = {
  85.   /*   {"","","",""}, */
  86.   {"path","-O","param1","output path"},
  87.   {"chroot","-%O","param1","default top path"},
  88.   {"mirror","-w","single",""},
  89.   {"mirror-wizard","-W","single",""},
  90.   {"get-files","-g","single",""},
  91.   {"quiet","-q","single",""},
  92.   {"mirrorlinks","-Y","single",""},
  93.   {"proxy","-P","param1","proxy name:port"},
  94.   {"httpproxy-ftp","-%f","param",""},
  95.   {"depth","-r","param",""},{"recurse-levels","-r","param",""},
  96.   {"ext-depth","-%e","param",""},
  97.   {"max-files","-m","param",""},
  98.   {"max-size","-M","param",""},
  99.   {"max-time","-E","param",""},
  100.   {"max-rate","-A","param",""},
  101.   {"max-pause","-G","param",""},
  102.   {"sockets","-c","param","number of simultaneous connections allowed"},{"socket","-c","param","number of simultaneous connections allowed"},{"connection","-c","param","number of simultaneous connections allowed"},
  103.   {"connection-per-second","-%c","param","number of connection per second allowed"},
  104.   {"timeout","-T","",""},
  105.   {"retries","-R","param","number of retries for non-fatal errors"},
  106.   {"min-rate","-J","param",""},
  107.   {"host-control","-H","param",""},
  108.   {"extended-parsing","-%P","param",""},
  109.   {"near","-n","single",""},
  110.   {"test","-t","single",""},
  111.   {"list","-%L","param1",""},
  112.   {"urllist","-%S","param1",""},
  113.   {"language","-%l","param1",""}, {"lang","-%l","param1",""},
  114.   {"structure","-N","param",""}, {"user-structure","-N","param1",""},
  115.   {"long-names","-L","param",""},
  116.   {"keep-links","-K","param",""},
  117.   {"replace-external","-x","single",""},
  118.   {"no-passwords","-%x","single",""},{"no-password","-%x","single",""},
  119.   {"include-query-string","-%q","single",""},
  120.   {"generate-errors","-o","single",""},
  121.   {"purge-old","-X","param",""},
  122.   {"cookies","-b","param",""},
  123.   {"check-type","-u","param",""},
  124.   {"assume","-%A","param1",""}, {"mimetype","-%A","param1",""},
  125.   {"parse-java","-j","param",""},
  126.   {"protocol","-@i","param",""},
  127.   {"robots","-s","param",""},
  128.   {"http-10","-%h","single",""},{"http-1.0","-%h","single",""},
  129.   {"no-compression","-%z","single",""},
  130.   {"tolerant","-%B","single",""},
  131.   {"updatehack","-%s","single",""}, {"sizehack","-%s","single",""},
  132.   {"user-agent","-F","param1","user-agent identity"},
  133.   {"footer","-%F","param1",""},
  134.   {"cache","-C","param","number of retries for non-fatal errors"},
  135.   {"store-all-in-cache","-k","single",""},
  136.   {"do-not-recatch","-%n","single",""},
  137.   {"do-not-log","-Q","single",""},
  138.   {"extra-log","-z","single",""},
  139.   {"debug-log","-Z","single",""},
  140.   {"verbose","-v","single",""},
  141.   {"file-log","-f","single",""},
  142.   {"single-log","-f2","single",""},
  143.   {"index","-I","single",""},
  144.   {"search-index","-%I","single",""},
  145.   {"priority","-p","param",""},
  146.   {"debug-headers","-%H","single",""},
  147.   {"userdef-cmd","-V","param1",""},
  148.   {"structure","-N","param1","user-defined structure"},
  149.   {"usercommand","-V","param1","user-defined command"},
  150.   {"display","-%v","single","show files transfered and other funny realtime information"},
  151.   {"dos83","-L0","single",""},
  152.   {"iso9660","-L2","single",""},
  153.   /* */
  154.  
  155.   /* DEPRECATED */
  156.   {"stay-on-same-dir","-S","single","stay on the same directory - DEPRECATED"},
  157.   {"can-go-down","-D","single","can only go down into subdirs - DEPRECATED"},
  158.   {"can-go-up","-U","single","can only go to upper directories- DEPRECATED"},
  159.   {"can-go-up-and-down","-B","single","can both go up&down into the directory structure - DEPRECATED"},
  160.   {"stay-on-same-address","-a","single","stay on the same address - DEPRECATED"},
  161.   {"stay-on-same-domain","-d","single","stay on the same principal domain - DEPRECATED"},
  162.   {"stay-on-same-tld","-l","single","stay on the same TLD (eg: .com) - DEPRECATED"},
  163.   {"go-everywhere","-e","single","go everywhere on the web - DEPRECATED"},
  164.  
  165.   /* Badly documented */
  166.   {"debug-testfilters","-#0","param1","debug: test filters"},
  167.   {"advanced-flushlogs","-#f","single",""},
  168.   {"advanced-maxfilters","-#F","param",""},
  169.   {"version","-#h","single",""},
  170.   {"debug-scanstdin","-#K","single",""},
  171.   {"advanced-maxlinks","-#L","single",""},
  172.   {"advanced-progressinfo","-#p","single",""},
  173.   {"catch-url","-#P","single","catch complex URL through proxy"},
  174.   {"debug-oldftp","-#R","single",""},
  175.   {"debug-xfrstats","-#T","single",""},
  176.   {"advanced-wait","-#u","single",""},
  177.   {"debug-ratestats","-#Z","single",""},
  178.   {"exec","-#!","param1",""},
  179.   {"fast-engine","-#X","single","Enable fast routines"},
  180.   {"debug-overflows","-#X0","single","Attempt to detect buffer overflows"},
  181.   {"debug-cache","-#C","param1","List files in the cache"},
  182.   
  183.   /* STANDARD ALIASES */
  184.   {"spider","-p0C0I0t","single",""},
  185.   {"testsite","-p0C0I0t","single",""},
  186.   {"testlinks","-r1p0C0I0t","single",""}, {"test","-r1p0C0I0t","single",""}, {"bookmark","-r1p0C0I0t","single",""},
  187.   {"mirror","-w","single",""},
  188.   {"testscan","-p0C0I0Q","single",""}, {"scan","-p0C0I0Q","single",""}, {"check","-p0C0I0Q","single",""},
  189.   {"skeleton","-p1","single",""},
  190.   {"preserve","-%p","single",""},
  191.   {"get","-qg","single",""},
  192.   {"update","-iC2","single",""},
  193.   {"continue","-iC1","single",""}, {"restart","-iC1","single",""},
  194.   {"continue","-i","single",""}, /* for help alias */
  195.   {"sucker","-r999","single",""},
  196.   {"help","-h","single",""}, {"documentation","-h","single",""}, {"doc","-h","single",""},
  197.   {"wide","-c32","single",""},
  198.   {"tiny","-c1","single",""},
  199.   {"ultrawide","-c48","single",""},
  200.   {"http10","-%h","single",""},
  201.   {"filelist","-%L","single",""}, {"list","-%L","single",""},
  202.   {"filterlist","-%S","single",""},
  203.   /* END OF ALIASES */
  204.  
  205.   /* Filters */
  206.   {"allow","+","param0","allow filter"},
  207.   {"deny","-","param0","deny filter"},
  208.   /* */
  209.  
  210.   /* URLs */
  211.   {"add","","param0","add URLs"},
  212.   /* */
  213.  
  214.   /* Specific */
  215.   {"user","-%U","param1","output path"},
  216.   /* */
  217.  
  218.   /* Internal */
  219.   {"catchurl","--catchurl","single","catch complex URL through proxy"},
  220.   {"updatehttrack","--updatehttrack","single","update HTTrack Website Copier"},
  221.   {"clean","--clean","single","clean up log files and cache"},
  222.   {"tide","--clean","single","clean up log files and cache"},
  223.   /* */
  224.  
  225.   {"","","",""}
  226. };
  227.  
  228.  
  229. /* 
  230.   Check for alias in command-line 
  231.   argc,argv     as in main()
  232.   n_arg         argument position
  233.   return_argv   a char[2][] where to put result
  234.   return_error  buffer in case of syntax error
  235.  
  236.   return value: number of arguments treated (0 if error)
  237. */
  238. int optalias_check(int argc,const char * const * argv,int n_arg,
  239.                    int* return_argc,char** return_argv,
  240.                    char* return_error) {
  241.   return_error[0]='\0';
  242.   *return_argc=1;
  243.   if (argv[n_arg][0]=='-')
  244.   if (argv[n_arg][1]=='-') {
  245.     char command[1000];
  246.     char param[1000];
  247.     char addcommand[256];
  248.     /* */
  249.     char* position;
  250.     int need_param=1;
  251.     //int return_param=0;
  252.     int pos;
  253.     command[0]=param[0]=addcommand[0]='\0';
  254.  
  255.     /* --sockets=8 */
  256.     if ( (position=strchr(argv[n_arg],'=')) ) {
  257.       /* Copy command */
  258.       strncatbuff(command,argv[n_arg]+2,(int) (position - (argv[n_arg]+2)) );
  259.       /* Copy parameter */
  260.       strcpybuff(param,position+1);
  261.     }
  262.     /* --nocache */
  263.     else if (strncmp(argv[n_arg]+2,"no",2)==0) {
  264.       strcpybuff(command,argv[n_arg]+4);
  265.       strcpybuff(param,"0");
  266.     }
  267.     /* --sockets 8 */
  268.     else {
  269.       if (strncmp(argv[n_arg]+2,"wide-",5)==0) {
  270.         strcpybuff(addcommand,"c32");
  271.         strcpybuff(command,strchr(argv[n_arg]+2,'-')+1);
  272.       } else if (strncmp(argv[n_arg]+2,"tiny-",5)==0) {
  273.         strcpybuff(addcommand,"c1");
  274.         strcpybuff(command,strchr(argv[n_arg]+2,'-')+1);
  275.       } else
  276.         strcpybuff(command,argv[n_arg]+2);
  277.       need_param=2;
  278.     }
  279.  
  280.     /* Now solve the alias */
  281.     pos=optalias_find(command);
  282.     if (pos>=0) {
  283.       /* Copy real name */
  284.       strcpybuff(command,hts_optalias[pos][1]);
  285.       /* With parameters? */
  286.       if (strncmp(hts_optalias[pos][2],"param",5)==0) {
  287.         /* Copy parameters? */
  288.         if (need_param == 2) {
  289.           if ((n_arg+1>=argc) || (argv[n_arg+1][0]=='-')) {  /* no supplemental parameter */
  290.             sprintf(return_error,
  291.               "Syntax error:\n\tOption %s needs to be followed by a parameter: %s <param>\n\t%s\n",
  292.               command,command,_NOT_NULL(optalias_help(command)));
  293.             return 0;
  294.           }
  295.           strcpybuff(param,argv[n_arg+1]);
  296.           need_param=2;
  297.         }
  298.       } else
  299.         need_param=1;
  300.  
  301.       /* Final result */
  302.  
  303.       /* Must be alone (-P /tmp) */
  304.       if (strcmp(hts_optalias[pos][2],"param1")==0) {
  305.         strcpybuff(return_argv[0],command);
  306.         strcpybuff(return_argv[1],param);
  307.         *return_argc=2;     /* 2 parameters returned */
  308.       } 
  309.       /* Alone with parameter (+*.gif) */
  310.       else if (strcmp(hts_optalias[pos][2],"param0")==0) {
  311.         /* Command */
  312.         strcpybuff(return_argv[0],command);
  313.         strcatbuff(return_argv[0],param);
  314.       }
  315.       /* Together (-c8) */
  316.       else {
  317.         /* Command */
  318.         strcpybuff(return_argv[0],command);
  319.         /* Parameters accepted */
  320.         if (strncmp(hts_optalias[pos][2],"param",5)==0) {
  321.           /* --cache=off or --index=on */
  322.           if (strcmp(param,"off")==0)
  323.             strcatbuff(return_argv[0],"0");
  324.           else if (strcmp(param,"on")==0) {
  325.             // on is the default
  326.             // strcatbuff(return_argv[0],"1");
  327.           } else
  328.             strcatbuff(return_argv[0],param);
  329.         }
  330.         *return_argc=1;     /* 1 parameter returned */
  331.       }
  332.     } else {
  333.       sprintf(return_error,"Unknown option: %s\n",command);
  334.       return 0;
  335.     }
  336.     return need_param;
  337.   }
  338.  
  339.   /* Check -P <path> */
  340.   {
  341.     int pos;
  342.     if ((pos=optreal_find(argv[n_arg]))>=0) {
  343.       if ( (strcmp(hts_optalias[pos][2],"param1")==0) || (strcmp(hts_optalias[pos][2],"param0")==0)) {
  344.         if ((n_arg+1>=argc) || (argv[n_arg+1][0]=='-')) {  /* no supplemental parameter */
  345.           sprintf(return_error,
  346.             "Syntax error:\n\tOption %s needs to be followed by a parameter: %s <param>\n\t%s\n",
  347.             argv[n_arg],argv[n_arg],_NOT_NULL(optalias_help(argv[n_arg])));
  348.           return 0;
  349.         }
  350.         /* Copy parameters */
  351.         strcpybuff(return_argv[0],argv[n_arg]);
  352.         strcpybuff(return_argv[1],argv[n_arg+1]);
  353.         /* And return */
  354.         *return_argc=2;     /* 2 parameters returned */
  355.         return 2;           /* 2 parameters used */
  356.       }
  357.     }
  358.   }
  359.   
  360.   /* Copy and return other unknown option */
  361.   strcpybuff(return_argv[0],argv[n_arg]);
  362.   return 1;
  363. }
  364.  
  365. /* Finds the <token> option alias and returns the index, or -1 if failed */
  366. int optalias_find(const char* token) {
  367.   if (token[0] != '\0') {
  368.     int i=0;
  369.     while(hts_optalias[i][0][0] != '\0') {
  370.       if (strcmp(token,hts_optalias[i][0])==0) {
  371.         return i;
  372.       }
  373.       i++;
  374.     }
  375.   }
  376.   return -1;
  377. }
  378.  
  379. /* Finds the <token> real option and returns the index, or -1 if failed */
  380. int optreal_find(const char* token) {
  381.   if (token[0] != '\0') {
  382.     int i=0;
  383.     while(hts_optalias[i][0][0] != '\0') {
  384.       if (strcmp(token,hts_optalias[i][1])==0) {
  385.         return i;
  386.       }
  387.       i++;
  388.     }
  389.   }
  390.   return -1;
  391. }
  392.  
  393. const char* optreal_value(int p) {
  394.   return hts_optalias[p][1];
  395. }
  396. const char* optalias_value(int p) {
  397.   return hts_optalias[p][0];
  398. }
  399. const char* opttype_value(int p) {
  400.   return hts_optalias[p][2];
  401. }
  402. const char* opthelp_value(int p) {
  403.   return hts_optalias[p][3];
  404. }
  405.  
  406. /* Help for option <token>, empty if not available, or NULL if unknown <token> */
  407. const char* optalias_help(const char* token) {
  408.   int pos=optalias_find(token);
  409.   if (pos>=0)
  410.     return hts_optalias[pos][3];
  411.   else
  412.     return NULL;
  413. }
  414.  
  415. /* Include a file to the current command line */
  416. /* example:
  417.   set sockets 8
  418.   index on
  419.   allow *.gif
  420.   deny ad.*
  421. */
  422. int optinclude_file(const char* name,
  423.                     int* argc,char** argv,char* x_argvblk,int* x_ptr) {
  424.   FILE* fp;
  425.   fp=fopen(name,"rb");
  426.   if (fp) {
  427.     char line[256];
  428.     int insert_after=1;       /* first, insert after program filename */
  429.     while(!feof(fp)) {
  430.       char *a,*b;
  431.       int result;
  432.       
  433.       /* read line */
  434.       linput(fp,line,250);
  435.       hts_lowcase(line);
  436.       if (strnotempty(line)) {
  437.         /* no comment line: # // ; */
  438.         if (strchr("#/;",line[0])==NULL) {
  439.           /* right trim */
  440.           a=line+strlen(line)-1;
  441.           while(is_realspace(*a)) *(a--) = '\0';
  442.           /* jump "set " and spaces */
  443.           a=line;
  444.           while(is_realspace(*a)) a++;
  445.           if (strncmp(a,"set",3)==0) {
  446.             if (is_realspace(*(a+3))) {
  447.               a+=4;
  448.             }
  449.           }
  450.           while(is_realspace(*a)) a++;
  451.           /* delete = ("sockets=8") */
  452.           if ( (b=strchr(a,'=')) )
  453.             *b=' ';
  454.           
  455.           /* isolate option and parameter */
  456.           b=a;
  457.           while( (!is_realspace(*b)) && (*b) ) b++;
  458.           if (*b) {
  459.             *b='\0';
  460.             b++;
  461.           }
  462.           /* a is now the option, b the parameter */
  463.           
  464.           {
  465.             int return_argc;
  466.             char return_error[256];
  467.             char  _tmp_argv[4][HTS_CDLMAXSIZE];
  468.             char*  tmp_argv[4];
  469.             tmp_argv[0]=_tmp_argv[0]; tmp_argv[1]=_tmp_argv[1]; tmp_argv[2]=_tmp_argv[2]; tmp_argv[3]=_tmp_argv[3];
  470.             strcpybuff(tmp_argv[0],"--");
  471.             strcatbuff(tmp_argv[0],a);
  472.             strcpybuff(tmp_argv[1],b);
  473.             
  474.             result=optalias_check(2,(const char * const *)tmp_argv,0,
  475.               &return_argc,(tmp_argv+2),
  476.               return_error);
  477.             if (!result) {
  478.               printf("%s\n",return_error);
  479.             } else {
  480.               int insert_after_argc;
  481.               /* Insert parameters BUT so that they can be in the same order */
  482.               /* temporary argc: Number of parameters after minus insert_after_argc */
  483.               insert_after_argc=(*argc)-insert_after;
  484.               cmdl_ins((tmp_argv[2]),insert_after_argc,(argv+insert_after),x_argvblk,(*x_ptr));
  485.               *argc=insert_after_argc+insert_after;
  486.               insert_after++;
  487.               /* Second one */
  488.               if (return_argc>1) {
  489.                 insert_after_argc=(*argc)-insert_after;
  490.                 cmdl_ins((tmp_argv[3]),insert_after_argc,(argv+insert_after),x_argvblk,(*x_ptr));
  491.                 *argc=insert_after_argc+insert_after;
  492.                 insert_after++;
  493.               }
  494.               /* increment to nbr of used parameters */
  495.               /* insert_after+=result; */
  496.             }
  497.           }
  498.         }
  499.         
  500.       }
  501.     }
  502.     fclose(fp);
  503.     return 1;
  504.   }
  505.   return 0;
  506. }
  507.  
  508. /* Get home directory, '.' if failed */
  509. /* example: /home/smith */
  510. char* hts_gethome(void) {
  511.   char* home = getenv( "HOME" );
  512.   if (home)
  513.     return home;
  514.   else
  515.     return ".";
  516. }
  517.  
  518. /* Convert ~/foo into /home/smith/foo */
  519. void expand_home(char* str) {
  520.   if (str[0] == '~') {
  521.     char tempo[HTS_URLMAXSIZE*2];
  522.     strcpybuff(tempo,hts_gethome());
  523.     strcatbuff(tempo,str+1);
  524.     strcpybuff(str,tempo);
  525.   }
  526. }
  527.